package org.third.integration.auth.jaas.hello;

import java.io.IOException;
import java.util.Map;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

public class HelloLoginModule implements LoginModule {
    private boolean isAuthenticated = false;
    private CallbackHandler callbackHandler;
    private javax.security.auth.Subject subject;
    private HelloPrincipal principal;

    public HelloLoginModule() {
        System.out.println(23);
    }

    @Override
    public void initialize(javax.security.auth.Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
        System.out.println(sharedState);
        System.out.println(options);
        this.subject = subject;
        this.callbackHandler = callbackHandler;
    }

    @Override
    public boolean login() throws LoginException {
        try {
            NameCallback nameCallback = new NameCallback("Type in userName: ");
            PasswordCallback passwordCallback = new PasswordCallback("Type in Password", false);
            final Callback[] calls = new Callback[] { nameCallback, passwordCallback };

            // 获取用户数据
            callbackHandler.handle(calls);
            String username = nameCallback.getName();
            String password = String.valueOf(passwordCallback.getPassword());

            // TODO 验证，如：查询数据库、LDAP。。。

            if (true) {// 验证通过
                principal = new HelloPrincipal(username);
                isAuthenticated = true;
            } else {
                throw new LoginException("user or password is wrong");
            }

        } catch (IOException e) {
            throw new LoginException("no such user");
        } catch (UnsupportedCallbackException e) {
            throw new LoginException("login failure");
        }
        return isAuthenticated;
    }

    /**
     * 验证后的处理,在Subject中加入用户对象
     */
    @Override
    public boolean commit() throws LoginException {
        if (isAuthenticated) {
            subject.getPrincipals().add(principal);
        } else {
            throw new LoginException("Authentication failure");
        }
        return isAuthenticated;
    }

    @Override
    public boolean abort() throws LoginException {
        return false;
    }

    @Override
    public boolean logout() throws LoginException {
        subject.getPrincipals().remove(principal);
        principal = null;
        return true;
    }
}